/*
 * @Author: wuqingchun
 * @Date: 2024-07-29 15:59:14
 * @Description: 
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-07-31 17:05:17
 */

#include <stdlib.h>

#include "ev_struct.h"
#include "ev_signal.h"
#include "ev_dispatcher.h"
#include "ev_epoll.h"
#include "ev_event.h"


EV_DISPATCHER_S* EV_dispatcher_Create()
{
    EV_DISPATCHER_OPS_S* pstDPOps = &g_stEvEpollOps;
    EV_DISPATCHER_S* pstDP;

    pstDP = pstDPOps->Create();
    if (pstDP == NULL)
    {
        return NULL;
    }

    pstDP->pstOps = pstDPOps;

    return pstDP;
}

void EV_dispatcher_Destroy(EV_DISPATCHER_S* pstDP)
{
    if (pstDP != NULL && pstDP->pstOps != NULL)
    {
        pstDP->pstOps->Destroy(pstDP);
    }
}

void EV_dispatcher_Dispatch(EV_DISPATCHER_S* pstDP)
{
    if (pstDP == NULL || pstDP->pstOps == NULL)
    {
        return ;
    }

    if (pstDP->iRunning)
    {
        return;
    }

    pstDP->iRunning = 1;

    int iDone = 0;
    int iErr;
    while (!iDone)
    {
        iErr = pstDP->pstOps->Dispatch(pstDP);
        if (iErr == -1)
        {
            break;
        }
    }
}

int EV_dispatcher_AddEvent(EV_DISPATCHER_S* pstDP, int iEventFd, unsigned int uiFlags, void (*pfCallback)(int, void*), void* pCBArg)
{
    if (pstDP == NULL || pstDP->pstOps == NULL)
    {
        return -1;
    }

    // 创建 EVENT

    EV_EVENT_S* pstEvent = EV_event_Create(pstDP, iEventFd, uiFlags, pfCallback, pCBArg);
    if (pstEvent == NULL)
    {
        return -1;
    }

    // 关联 DP 和 EVENT
    pstDP->apstEvent[0] = pstEvent;
    
    if (uiFlags & EV_FLAG_SIGNAL)
    {
        EV_signal_Add(iEventFd);

        pstDP->pstOps->AddEvent(pstDP, &pstDP->stSigEvent);
    }
    else if (uiFlags & EV_FLAG_IO)
    {
        pstDP->pstOps->AddEvent(pstDP, pstEvent);
    }

    return 0;
}

int EV_dispatcher_DeleteEvent(EV_DISPATCHER_S* pstDP)
{
    pstDP->pstOps->DeleteEvent();
}